﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace FileHelper
{
    /// <summary>
    /// ini文件处理辅助类
    /// </summary>
    public static class Ini
    {
        private static string DefaultIniPath = string.Empty;

        /// <summary>
        /// 设置ini文件的默认地址
        /// </summary>
        /// <param name="iniPath">ini文件全路径</param>
        public static void SetDefaultIniFilePath(string iniPath)
        {
            if (!string.IsNullOrWhiteSpace(iniPath))
            {
                DefaultIniPath = iniPath;
            }
        }

        /// <summary> 
        /// 写入INI文件 
        /// </summary> 
        /// <param name="section">项目名称(如 [TypeName] )</param> 
        /// <param name="key">键</param> 
        /// <param name="value">值</param> 
        /// <param name="iniFilePath">ini文件全路径</param>
        public static void WriteValue(string section, string key, string value = "Value", string iniFilePath = null)
        {
            iniFilePath ??= DefaultIniPath;
            if (!File.Exists(iniFilePath))
            {
                File.Create(iniFilePath).Close();
            }

            if (!string.IsNullOrWhiteSpace(section) && !string.IsNullOrWhiteSpace(key))
            {
                var sectionKey = ($"[{section}]", $"{key}=");
                var lines = File.ReadAllLines(iniFilePath);
                if (lines.Length == 0)
                {
                    File.AppendAllLines(iniFilePath, new[] { $"{sectionKey.Item1}{Environment.NewLine}{sectionKey.Item2}{value}" });
                }
                else
                {

                    if (Array.IndexOf(lines, sectionKey.Item1) > -1)
                    {
                        var exists = false;
                        for (var i = 0; i < lines.Length; i++)
                        {
                            if (exists)
                            {
                                //以下仅取子项
                                if (lines[i].StartsWith(sectionKey.Item2))
                                {
                                    lines[i] = $"{sectionKey.Item2}{value}";
                                    exists = false;
                                }
                                else if (lines[i].StartsWith("["))
                                {
                                    lines[i] = $"{sectionKey.Item2}{value}{Environment.NewLine}{lines[i]}";
                                    exists = false;
                                }
                                else if (i == lines.Length - 1)
                                {
                                    //说明是最后一行
                                    File.AppendAllLines(iniFilePath, new[] { $"{sectionKey.Item2}{value}" });
                                    break;
                                }
                                if (exists)
                                {
                                    continue;
                                }
                                File.WriteAllLines(iniFilePath, lines);
                                break;
                            }
                            else
                            {
                                exists = lines[i].Equals(sectionKey.Item1);
                            }
                        }
                    }
                    else
                    {
                        if (lines[lines.Length - 1].EndsWith("="))
                        {
                            File.AppendAllLines(iniFilePath, new[] { "", $"{sectionKey.Item1}", $"{sectionKey.Item2}{value}" });
                        }
                        else
                        {
                            File.AppendAllLines(iniFilePath, new[] { $"{sectionKey.Item1}", $"{sectionKey.Item2}{value}" });
                        }
                    }
                }
            }
        }

        /// <summary> 
        /// 读出INI文件 
        /// </summary> 
        /// <param name="section">项目名称(如 [TypeName] )</param> 
        /// <param name="key">键</param>
        /// <param name="iniFilePath">ini文件全路径</param>
        public static string ReadValue(string section, string key = "Value", string iniFilePath = null)
        {
            iniFilePath ??= DefaultIniPath;
            if (!string.IsNullOrWhiteSpace(iniFilePath) && iniFilePath.EndsWith(".ini") && File.Exists(iniFilePath) && !string.IsNullOrWhiteSpace(section) && !string.IsNullOrWhiteSpace(key))
            {
                var lines = File.ReadAllLines(iniFilePath);

                var sectionKey = ($"[{section}]", $"{key}=");

                if (lines.Length > 0 && Array.IndexOf(lines, sectionKey.Item1) > -1)
                {
                    var exists = false;
                    for (var i = 0; i < lines.Length; i++)
                    {
                        if (lines[i] == sectionKey.Item1)
                        {
                            exists = true;
                        }
                        else if (exists)
                        {
                            //这里是key级
                            if (lines[i].StartsWith(sectionKey.Item2))
                            {
                                return lines[i].Replace(sectionKey.Item2, "");
                            }

                            if (lines[i].Equals("]"))
                            {
                                break;
                            }
                        }
                    }
                }
            }
            return string.Empty;
        }
        /// <summary> 
        /// 读出INI文件_节点下所有键值 
        /// </summary> 
        /// <param name="section">项目名称(如 [TypeName] )</param> 
        /// <param name="iniFilePath">ini文件全路径</param>
        public static Dictionary<string, string> ReadAllValue(string section, string iniFilePath = null)
        {
            iniFilePath ??= DefaultIniPath;
            Dictionary<string, string> dic = new Dictionary<string, string>();
            if (!string.IsNullOrWhiteSpace(iniFilePath) && iniFilePath.EndsWith(".ini") && File.Exists(iniFilePath) && !string.IsNullOrWhiteSpace(section))
            {
                var lines = File.ReadAllLines(iniFilePath);

                var sectionKey = ($"[{section}]");
                if (lines.Length > 0 && Array.IndexOf(lines, sectionKey) > -1)
                {
                    var exists = false;
                    for (var i = 0; i < lines.Length; i++)
                    {
                        if (lines[i] == sectionKey)
                        {
                            exists = true;
                        }
                        else if (exists)
                        {
                            if (lines[i].Contains("[") && lines[i].Contains("]")) break;
                            if (lines[i].StartsWith("#") || string.IsNullOrEmpty(lines[i].Trim()) || !lines[i].Contains("=")) continue; 

                            //这里是key级
                            string[] key_value = lines[i].Split('=');
                            if (key_value.Length > 0 && key_value.Length < 2)
                            {
                                dic.Add(key_value[0], "");
                            }
                            else if (key_value.Length >= 2)
                            {
                                dic.Add(key_value[0], key_value[1]);
                            }
                            if (lines[i].Equals("]"))
                            {
                                break;
                            }
                        }
                    }
                }
            }
            return dic;
        }
        ///<summary> 
        ///删除这个项现有的字串。 
        ///</summary> 
        ///<param name= "section"> 要设置的项名或条目名 </param> 
        ///<param name= "key"> 要删除的项名或条目名</param> 
        ///<param name="iniFilePath">ini文件全路径</param>
        public static void DeleteKey(string section, string key, string iniFilePath = null)
        {
            iniFilePath ??= DefaultIniPath;
            if (!string.IsNullOrWhiteSpace(iniFilePath) && iniFilePath.EndsWith(".ini") && File.Exists(iniFilePath) && !string.IsNullOrWhiteSpace(section) && !string.IsNullOrWhiteSpace(key))
            {
                var lines = File.ReadAllLines(iniFilePath);

                var sectionKey = ($"[{section}]", $"{key}=");

                if (lines.Length > 0 && Array.IndexOf(lines, sectionKey.Item1) > -1)
                {
                    var exists = false;
                    for (var i = 0; i < lines.Length; i++)
                    {
                        if (lines[i] == sectionKey.Item1)
                        {
                            exists = true;
                        }
                        else if (exists)
                        {
                            //这里是key级
                            if (lines[i].StartsWith(sectionKey.Item2))
                            {
                                lines[i] = sectionKey.Item2;
                                File.WriteAllLines(iniFilePath, lines);
                                break;
                            }

                            if (lines[i].Equals("]"))
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }

        ///<summary> 
        ///删除这个项现有健值
        ///</summary> 
        ///<param name= "section"> 要设置的项名或条目名 </param> 
        ///<param name= "key"> 要删除的项名或条目名</param> 
        ///<param name="iniFilePath">ini文件全路径</param>
        public static void DeleteKeyAndValue(string section, string key, string iniFilePath = null)
        {
            iniFilePath ??= DefaultIniPath;
            if (!string.IsNullOrWhiteSpace(iniFilePath) && iniFilePath.EndsWith(".ini") && File.Exists(iniFilePath) && !string.IsNullOrWhiteSpace(section) && !string.IsNullOrWhiteSpace(key))
            {
                var lines = File.ReadAllLines(iniFilePath);

                var sectionKey = ($"[{section}]", $"");

                if (lines.Length > 0 && Array.IndexOf(lines, sectionKey.Item1) > -1)
                {
                    var exists = false;
                    for (var i = 0; i < lines.Length; i++)
                    {
                        if (lines[i] == sectionKey.Item1)
                        {
                            exists = true;
                        }
                        else if (exists)
                        {
                            //这里是key级
                            if (lines[i].StartsWith(sectionKey.Item2))
                            {
                                lines[i] = sectionKey.Item2;
                                File.WriteAllLines(iniFilePath, lines);
                                break;
                            }

                            if (lines[i].Equals("]"))
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }

        ///<summary> 
        ///删除这个小节的所有设置项。 
        ///</summary> 
        ///<param name= "section"> 要删除的小节名称</param> 
        ///<param name="iniFilePath">ini文件全路径</param>
        public static void DeleteSection(string section, string iniFilePath)
        {
            if (!string.IsNullOrWhiteSpace(iniFilePath) && iniFilePath.EndsWith(".ini") && File.Exists(iniFilePath) && !string.IsNullOrWhiteSpace(section))
            {
                var lines = File.ReadAllLines(iniFilePath);

                if (lines.Length > 0 && Array.IndexOf(lines, $"[{section}]") > -1)
                {
                    var exists = false;
                    for (var i = 0; i < lines.Length; i++)
                    {
                        if (lines[i] == $"[{section}]")
                        {
                            exists = true;
                            lines[i] = "----*----";
                        }
                        else if (exists)
                        {
                            //这里是key级
                            if (lines[i].StartsWith("["))
                            {
                                break;
                            }

                            lines[i] = "----*----";
                        }
                    }

                    File.WriteAllLines(iniFilePath, lines.Where(x => x != "----*----").ToArray());
                }
            }
        }
    }
}
